package fanketly.core.lib.base.utils

import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType

/**
 *Create by Fanketly on 2022/7/1
 *Gitee:https://gitee.com/fanketly
 *desc:
 */
object ViewBindingUtils {

    // 日志 TAG
    private val TAG = ViewBindingUtils::class.java.simpleName

    /**
     * 获取 VB Class
     * @param clazz javaClass
     */
    fun <VB : ViewBinding, T : Any> getClassVB(clazz: Class<T>): Class<VB> {
        val parameterizedType = clazz.genericSuperclass as ParameterizedType
        val types = parameterizedType.actualTypeArguments
        for (type in types) {
            if (type.toString().endsWith("Binding")) {
                return type as Class<VB>
            }
        }
        return types[0] as Class<VB>
    }

    /**
     * ViewBinding 初始化处理 ( 通过传入 javaClass )
     * @param inflater  [LayoutInflater]
     * @param container [ViewGroup]
     * @param clazz     javaClass
     */
    fun <VB : ViewBinding, T : Any> viewBindingJavaClass(
        inflater: LayoutInflater? = null,
        container: ViewGroup? = null,
        isAttach: Boolean,
        clazz: Class<T>
    ): VB {
        try {
            return viewBinding(
                inflater, container, isAttach, getClassVB(clazz)
            )
        } catch (e: Exception) {
            Log.e(TAG, e.toString())
        }
        throw Exception("${clazz.simpleName} viewBinding error")
    }

    /**
     * ViewBinding 初始化处理
     * @param inflater  [LayoutInflater]
     * @param container [ViewGroup]
     * @param clazz     VB Class
     */
    fun <VB : ViewBinding> viewBinding(
        inflater: LayoutInflater? = null,
        container: ViewGroup? = null,
        isAttach: Boolean,
        clazz: Class<VB>
    ): VB {
        try {
            val method = clazz.getMethod(
                "inflate",
                LayoutInflater::class.java,
                ViewGroup::class.java,
                Boolean::class.java
            )
            return method.invoke(null, inflater, container, isAttach) as VB
        } catch (e: Exception) {
            Log.e(TAG, e.toString())
        }
        throw Exception("${clazz.simpleName} viewBinding error")
    }
}